<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title></title>
  <style>
    .bezier {
      width: 1200px;
      height: 700px;
      position: relative;
      box-shadow: 10px 10px 12px rgba(0, 0, 0, 0.5);
    }
    .bezier canvas {
      width: 100%;
      height: 100%;
      position: absolute;
    }
    .bezier .point {
      width: 20px;
      height: 20px;
      position: absolute;
      left: 0;
      top: 0;
      background-color: rgb(80, 207, 230);
      border-radius: 50%;
    }
    #info {
      position: absolute;
      right: 30px;
      bottom: 30px;
    }
  </style>
</head>
<body>
  <div class="bezier">
    <canvas id="canvas"></canvas>
    <div class="point"></div>
    <div class="point"></div>
    <div class="point"></div>
    <div class="point"></div>
    <p id="info"></p>
  </div>
  <script src='../drawGrids/DrawGrids.js'></script>
  <script>
    const points = document.querySelectorAll('.point');
    const info = document.getElementById('info');
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    
    const W = canvas.width = 1200;
    const H = canvas.height = 700;
    
    let initPosition = [
      [200, 120],
      [200, 400],
      [900, 120],
      [900, 400]
    ];
    
    linePoint(initPosition);
    getInfo(initPosition);
    drawBezierCurve(initPosition);
    
    initPosition.forEach((item, i) => {
      points[i].style.left = item[0] - points[i].offsetWidth / 2 + 'px';
      points[i].style.top = item[1] - points[i].offsetHeight / 2 + 'px';
      
      points[i].onmousedown = function (e){
        e.preventDefault();
        
        let event = eventWrap(this.parentNode, e);
        let dx = event.X - this.offsetLeft, dy = event.Y - this.offsetTop;
        let _this = this;
        
        this.parentNode.onmousemove = function (e){
          let event = eventWrap(this, e);
          
          let L = event.X - dx;
          let T = event.Y - dy;
          
          if(L <= 0) L = 0;
          if(T <= 0) T = 0;
          
          if(L >= this.clientWidth - _this.offsetWidth){
            L = this.clientWidth - _this.offsetWidth;
          }
          if(T >= this.clientHeight - _this.offsetHeight){
            T = this.clientHeight - _this.offsetHeight;
          }
            
          _this.style.left = L + 'px';
          _this.style.top = T + 'px';
          
          initPosition[i][0] = _this.offsetLeft + _this.offsetWidth / 2;
          initPosition[i][1] = _this.offsetTop + _this.offsetHeight / 2;
          
          getInfo(initPosition);
          drawBezierCurve(initPosition);
        };
        this.parentNode.onmouseup = function (){
          this.onmouseup = this.onmousemove = null;
        };
      };
    });
    
    function drawBezierCurve(data){
      ctx.clearRect(0, 0, W, H);
      DrawGrids(ctx, 'hsla(0, 0%, 0%, 0.2)', 20, 20);
      
      ctx.strokeStyle = 'rgb(125, 233, 188)';
      ctx.lineWidth = 1;
      linePoint(initPosition);
      
      ctx.strokeStyle = 'rgb(250, 89, 89)';
      ctx.lineWidth = 6;
      ctx.beginPath();
      ctx.lineTo(data[0][0], data[0][1]);
      ctx.bezierCurveTo(
        data[1][0], data[1][1],
        data[2][0], data[2][1],
        data[3][0], data[3][1]
      );
      ctx.stroke();
    };
    
    function getInfo(data){
      let start = data[0];
      let cp1 = data[1];
      let cp2 = data[2];
      let end = data[3];
      let currentCode = `ctx.lineTo(${start[0]}, ${start[1]});<br/>ctx.bezierCurveTo(${cp1[0]}, ${cp1[1]}, ${cp2[0]}, ${cp2[1]}, ${end[0]}, ${end[1]});`;
      info.innerHTML = currentCode;
    }
    
    
    function linePoint(data){
      data.forEach(function(item, i) {
        if(!(i%2)) ctx.beginPath();
        ctx.lineTo(item[0], item[1]);
        ctx.stroke();
      });
    }
    
    function eventWrap(ele, event){
      const borderSize = parseFloat(getComputedStyle(canvas)['border-width']);
      const rect = ele.getBoundingClientRect();
      const X = event.pageX - rect.left - borderSize;
      const Y = event.pageY - rect.top - borderSize;
      return {
        X, 
        Y,
        ev: event
      }
    }
  </script>
</body>
</html>